summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/common/thread.cpp24
-rw-r--r--src/core/file_sys/system_archive/system_version.cpp4
-rw-r--r--src/core/hle/service/ptm/ts.cpp40
-rw-r--r--src/core/hle/service/ptm/ts.h6
-rw-r--r--src/core/hle/service/set/set_sys.cpp49
-rw-r--r--src/core/memory/cheat_engine.cpp23
-rw-r--r--src/shader_recompiler/backend/glsl/emit_glsl.cpp1
-rw-r--r--src/shader_recompiler/backend/glsl/emit_glsl_warp.cpp12
-rw-r--r--src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp23
-rw-r--r--src/shader_recompiler/backend/spirv/spirv_emit_context.h36
-rw-r--r--src/shader_recompiler/profile.h4
-rw-r--r--src/video_core/renderer_vulkan/vk_pipeline_cache.cpp6
-rw-r--r--src/video_core/vulkan_common/vulkan_device.cpp35
-rw-r--r--src/video_core/vulkan_common/vulkan_device.h18
-rw-r--r--src/yuzu/configuration/configure_vibration.cpp10
15 files changed, 203 insertions, 88 deletions
diff --git a/src/common/thread.cpp b/src/common/thread.cpp
index 919e33af9..34cc1527b 100644
--- a/src/common/thread.cpp
+++ b/src/common/thread.cpp
@@ -11,6 +11,7 @@
#include <mach/mach.h>
#elif defined(_WIN32)
#include <windows.h>
+#include "common/string_util.h"
#else
#if defined(__Bitrig__) || defined(__DragonFly__) || defined(__FreeBSD__) || defined(__OpenBSD__)
#include <pthread_np.h>
@@ -82,29 +83,8 @@ void SetCurrentThreadPriority(ThreadPriority new_priority) {
#ifdef _MSC_VER
// Sets the debugger-visible name of the current thread.
-// Uses trick documented in:
-// https://docs.microsoft.com/en-us/visualstudio/debugger/how-to-set-a-thread-name-in-native-code
void SetCurrentThreadName(const char* name) {
- static const DWORD MS_VC_EXCEPTION = 0x406D1388;
-
-#pragma pack(push, 8)
- struct THREADNAME_INFO {
- DWORD dwType; // must be 0x1000
- LPCSTR szName; // pointer to name (in user addr space)
- DWORD dwThreadID; // thread ID (-1=caller thread)
- DWORD dwFlags; // reserved for future use, must be zero
- } info;
-#pragma pack(pop)
-
- info.dwType = 0x1000;
- info.szName = name;
- info.dwThreadID = std::numeric_limits<DWORD>::max();
- info.dwFlags = 0;
-
- __try {
- RaiseException(MS_VC_EXCEPTION, 0, sizeof(info) / sizeof(ULONG_PTR), (ULONG_PTR*)&info);
- } __except (EXCEPTION_CONTINUE_EXECUTION) {
- }
+ SetThreadDescription(GetCurrentThread(), UTF8ToUTF16W(name).data());
}
#else // !MSVC_VER, so must be POSIX threads
diff --git a/src/core/file_sys/system_archive/system_version.cpp b/src/core/file_sys/system_archive/system_version.cpp
index bd493ecca..e4751c2b4 100644
--- a/src/core/file_sys/system_archive/system_version.cpp
+++ b/src/core/file_sys/system_archive/system_version.cpp
@@ -1,6 +1,7 @@
// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
+#include "common/logging/log.h"
#include "core/file_sys/system_archive/system_version.h"
#include "core/file_sys/vfs_vector.h"
#include "core/hle/api_version.h"
@@ -12,6 +13,9 @@ std::string GetLongDisplayVersion() {
}
VirtualDir SystemVersion() {
+ LOG_WARNING(Common_Filesystem, "called - Using hardcoded firmware version '{}'",
+ GetLongDisplayVersion());
+
VirtualFile file = std::make_shared<VectorVfsFile>(std::vector<u8>(0x100), "file");
file->WriteObject(HLE::ApiVersion::HOS_VERSION_MAJOR, 0);
file->WriteObject(HLE::ApiVersion::HOS_VERSION_MINOR, 1);
diff --git a/src/core/hle/service/ptm/ts.cpp b/src/core/hle/service/ptm/ts.cpp
index ca064dd90..652f38b97 100644
--- a/src/core/hle/service/ptm/ts.cpp
+++ b/src/core/hle/service/ptm/ts.cpp
@@ -9,6 +9,35 @@
namespace Service::PTM {
+enum class Location : u8 {
+ Internal,
+ External,
+};
+
+class ISession : public ServiceFramework<ISession> {
+public:
+ explicit ISession(Core::System& system_) : ServiceFramework{system_, "ISession"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "GetTemperatureRange"},
+ {2, nullptr, "SetMeasurementMode"},
+ {4, &ISession::GetTemperature, "GetTemperature"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+
+private:
+ void GetTemperature(HLERequestContext& ctx) {
+ constexpr f32 temperature = 35;
+
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(ResultSuccess);
+ rb.Push(temperature);
+ }
+};
+
TS::TS(Core::System& system_) : ServiceFramework{system_, "ts"} {
// clang-format off
static const FunctionInfo functions[] = {
@@ -16,7 +45,7 @@ TS::TS(Core::System& system_) : ServiceFramework{system_, "ts"} {
{1, &TS::GetTemperature, "GetTemperature"},
{2, nullptr, "SetMeasurementMode"},
{3, &TS::GetTemperatureMilliC, "GetTemperatureMilliC"},
- {4, nullptr, "OpenSession"},
+ {4, &TS::OpenSession, "OpenSession"},
};
// clang-format on
@@ -47,4 +76,13 @@ void TS::GetTemperatureMilliC(HLERequestContext& ctx) {
rb.Push(temperature);
}
+void TS::OpenSession(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ [[maybe_unused]] const u32 device_code = rp.Pop<u32>();
+
+ IPC::ResponseBuilder rb{ctx, 2, 0, 1};
+ rb.Push(ResultSuccess);
+ rb.PushIpcInterface<ISession>(system);
+}
+
} // namespace Service::PTM
diff --git a/src/core/hle/service/ptm/ts.h b/src/core/hle/service/ptm/ts.h
index c3f43d5a3..a10a91a64 100644
--- a/src/core/hle/service/ptm/ts.h
+++ b/src/core/hle/service/ptm/ts.h
@@ -14,13 +14,9 @@ public:
~TS() override;
private:
- enum class Location : u8 {
- Internal,
- External,
- };
-
void GetTemperature(HLERequestContext& ctx);
void GetTemperatureMilliC(HLERequestContext& ctx);
+ void OpenSession(HLERequestContext& ctx);
};
} // namespace Service::PTM
diff --git a/src/core/hle/service/set/set_sys.cpp b/src/core/hle/service/set/set_sys.cpp
index 165b97dad..ec3af80af 100644
--- a/src/core/hle/service/set/set_sys.cpp
+++ b/src/core/hle/service/set/set_sys.cpp
@@ -5,8 +5,13 @@
#include "common/logging/log.h"
#include "common/settings.h"
#include "common/string_util.h"
+#include "core/core.h"
+#include "core/file_sys/content_archive.h"
#include "core/file_sys/errors.h"
-#include "core/file_sys/system_archive/system_version.h"
+#include "core/file_sys/nca_metadata.h"
+#include "core/file_sys/registered_cache.h"
+#include "core/file_sys/romfs.h"
+#include "core/file_sys/system_archive/system_archive.h"
#include "core/hle/service/filesystem/filesystem.h"
#include "core/hle/service/ipc_helpers.h"
#include "core/hle/service/set/set.h"
@@ -22,18 +27,30 @@ enum class GetFirmwareVersionType {
Version2,
};
-void GetFirmwareVersionImpl(HLERequestContext& ctx, GetFirmwareVersionType type) {
- LOG_WARNING(Service_SET, "called - Using hardcoded firmware version '{}'",
- FileSys::SystemArchive::GetLongDisplayVersion());
-
+void GetFirmwareVersionImpl(Core::System& system, HLERequestContext& ctx,
+ GetFirmwareVersionType type) {
ASSERT_MSG(ctx.GetWriteBufferSize() == 0x100,
"FirmwareVersion output buffer must be 0x100 bytes in size!");
- // Instead of using the normal procedure of checking for the real system archive and if it
- // doesn't exist, synthesizing one, I feel that that would lead to strange bugs because a
- // used is using a really old or really new SystemVersion title. The synthesized one ensures
- // consistence (currently reports as 5.1.0-0.0)
- const auto archive = FileSys::SystemArchive::SystemVersion();
+ constexpr u64 FirmwareVersionSystemDataId = 0x0100000000000809;
+ auto& fsc = system.GetFileSystemController();
+
+ // Attempt to load version data from disk
+ const FileSys::RegisteredCache* bis_system{};
+ std::unique_ptr<FileSys::NCA> nca{};
+ FileSys::VirtualDir romfs{};
+
+ bis_system = fsc.GetSystemNANDContents();
+ if (bis_system) {
+ nca = bis_system->GetEntry(FirmwareVersionSystemDataId, FileSys::ContentRecordType::Data);
+ }
+ if (nca) {
+ romfs = FileSys::ExtractRomFS(nca->GetRomFS());
+ }
+ if (!romfs) {
+ romfs = FileSys::ExtractRomFS(
+ FileSys::SystemArchive::SynthesizeSystemArchive(FirmwareVersionSystemDataId));
+ }
const auto early_exit_failure = [&ctx](std::string_view desc, Result code) {
LOG_ERROR(Service_SET, "General failure while attempting to resolve firmware version ({}).",
@@ -42,13 +59,7 @@ void GetFirmwareVersionImpl(HLERequestContext& ctx, GetFirmwareVersionType type)
rb.Push(code);
};
- if (archive == nullptr) {
- early_exit_failure("The system version archive couldn't be synthesized.",
- FileSys::ERROR_FAILED_MOUNT_ARCHIVE);
- return;
- }
-
- const auto ver_file = archive->GetFile("file");
+ const auto ver_file = romfs->GetFile("file");
if (ver_file == nullptr) {
early_exit_failure("The system version archive didn't contain the file 'file'.",
FileSys::ERROR_INVALID_ARGUMENT);
@@ -87,12 +98,12 @@ void SET_SYS::SetLanguageCode(HLERequestContext& ctx) {
void SET_SYS::GetFirmwareVersion(HLERequestContext& ctx) {
LOG_DEBUG(Service_SET, "called");
- GetFirmwareVersionImpl(ctx, GetFirmwareVersionType::Version1);
+ GetFirmwareVersionImpl(system, ctx, GetFirmwareVersionType::Version1);
}
void SET_SYS::GetFirmwareVersion2(HLERequestContext& ctx) {
LOG_DEBUG(Service_SET, "called");
- GetFirmwareVersionImpl(ctx, GetFirmwareVersionType::Version2);
+ GetFirmwareVersionImpl(system, ctx, GetFirmwareVersionType::Version2);
}
void SET_SYS::GetAccountSettings(HLERequestContext& ctx) {
diff --git a/src/core/memory/cheat_engine.cpp b/src/core/memory/cheat_engine.cpp
index a06e99166..53a89cc8f 100644
--- a/src/core/memory/cheat_engine.cpp
+++ b/src/core/memory/cheat_engine.cpp
@@ -19,16 +19,23 @@ namespace Core::Memory {
namespace {
constexpr auto CHEAT_ENGINE_NS = std::chrono::nanoseconds{1000000000 / 12};
-std::string_view ExtractName(std::string_view data, std::size_t start_index, char match) {
+std::string_view ExtractName(std::size_t& out_name_size, std::string_view data,
+ std::size_t start_index, char match) {
auto end_index = start_index;
while (data[end_index] != match) {
++end_index;
- if (end_index > data.size() ||
- (end_index - start_index - 1) > sizeof(CheatDefinition::readable_name)) {
+ if (end_index > data.size()) {
return {};
}
}
+ out_name_size = end_index - start_index;
+
+ // Clamp name if it's too big
+ if (out_name_size > sizeof(CheatDefinition::readable_name)) {
+ end_index = start_index + sizeof(CheatDefinition::readable_name);
+ }
+
return data.substr(start_index, end_index - start_index);
}
} // Anonymous namespace
@@ -113,7 +120,8 @@ std::vector<CheatEntry> TextCheatParser::Parse(std::string_view data) const {
return {};
}
- const auto name = ExtractName(data, i + 1, '}');
+ std::size_t name_size{};
+ const auto name = ExtractName(name_size, data, i + 1, '}');
if (name.empty()) {
return {};
}
@@ -125,12 +133,13 @@ std::vector<CheatEntry> TextCheatParser::Parse(std::string_view data) const {
.definition.readable_name[out[*current_entry].definition.readable_name.size() - 1] =
'\0';
- i += name.length() + 1;
+ i += name_size + 1;
} else if (data[i] == '[') {
current_entry = out.size();
out.emplace_back();
- const auto name = ExtractName(data, i + 1, ']');
+ std::size_t name_size{};
+ const auto name = ExtractName(name_size, data, i + 1, ']');
if (name.empty()) {
return {};
}
@@ -142,7 +151,7 @@ std::vector<CheatEntry> TextCheatParser::Parse(std::string_view data) const {
.definition.readable_name[out[*current_entry].definition.readable_name.size() - 1] =
'\0';
- i += name.length() + 1;
+ i += name_size + 1;
} else if (::isxdigit(data[i])) {
if (!current_entry || out[*current_entry].definition.num_opcodes >=
out[*current_entry].definition.opcodes.size()) {
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl.cpp b/src/shader_recompiler/backend/glsl/emit_glsl.cpp
index d91e04446..66ecfc9f7 100644
--- a/src/shader_recompiler/backend/glsl/emit_glsl.cpp
+++ b/src/shader_recompiler/backend/glsl/emit_glsl.cpp
@@ -242,6 +242,7 @@ std::string EmitGLSL(const Profile& profile, const RuntimeInfo& runtime_info, IR
}
if (program.info.uses_subgroup_shuffles) {
ctx.header += "bool shfl_in_bounds;";
+ ctx.header += "uint shfl_result;";
}
ctx.code.insert(0, ctx.header);
ctx.code += '}';
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_warp.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_warp.cpp
index 1245c9429..f9be5de1c 100644
--- a/src/shader_recompiler/backend/glsl/emit_glsl_warp.cpp
+++ b/src/shader_recompiler/backend/glsl/emit_glsl_warp.cpp
@@ -141,7 +141,8 @@ void EmitShuffleIndex(EmitContext& ctx, IR::Inst& inst, std::string_view value,
const auto src_thread_id{fmt::format("({})|({})", lhs, min_thread_id)};
ctx.Add("shfl_in_bounds=int({})<=int({});", src_thread_id, max_thread_id);
SetInBoundsFlag(ctx, inst);
- ctx.AddU32("{}=shfl_in_bounds?readInvocationARB({},{}):{};", inst, value, src_thread_id, value);
+ ctx.Add("shfl_result=readInvocationARB({},{});", value, src_thread_id);
+ ctx.AddU32("{}=shfl_in_bounds?shfl_result:{};", inst, value);
}
void EmitShuffleUp(EmitContext& ctx, IR::Inst& inst, std::string_view value, std::string_view index,
@@ -158,7 +159,8 @@ void EmitShuffleUp(EmitContext& ctx, IR::Inst& inst, std::string_view value, std
const auto src_thread_id{fmt::format("({}-{})", THREAD_ID, index)};
ctx.Add("shfl_in_bounds=int({})>=int({});", src_thread_id, max_thread_id);
SetInBoundsFlag(ctx, inst);
- ctx.AddU32("{}=shfl_in_bounds?readInvocationARB({},{}):{};", inst, value, src_thread_id, value);
+ ctx.Add("shfl_result=readInvocationARB({},{});", value, src_thread_id);
+ ctx.AddU32("{}=shfl_in_bounds?shfl_result:{};", inst, value);
}
void EmitShuffleDown(EmitContext& ctx, IR::Inst& inst, std::string_view value,
@@ -175,7 +177,8 @@ void EmitShuffleDown(EmitContext& ctx, IR::Inst& inst, std::string_view value,
const auto src_thread_id{fmt::format("({}+{})", THREAD_ID, index)};
ctx.Add("shfl_in_bounds=int({})<=int({});", src_thread_id, max_thread_id);
SetInBoundsFlag(ctx, inst);
- ctx.AddU32("{}=shfl_in_bounds?readInvocationARB({},{}):{};", inst, value, src_thread_id, value);
+ ctx.Add("shfl_result=readInvocationARB({},{});", value, src_thread_id);
+ ctx.AddU32("{}=shfl_in_bounds?shfl_result:{};", inst, value);
}
void EmitShuffleButterfly(EmitContext& ctx, IR::Inst& inst, std::string_view value,
@@ -193,7 +196,8 @@ void EmitShuffleButterfly(EmitContext& ctx, IR::Inst& inst, std::string_view val
const auto src_thread_id{fmt::format("({}^{})", THREAD_ID, index)};
ctx.Add("shfl_in_bounds=int({})<=int({});", src_thread_id, max_thread_id);
SetInBoundsFlag(ctx, inst);
- ctx.AddU32("{}=shfl_in_bounds?readInvocationARB({},{}):{};", inst, value, src_thread_id, value);
+ ctx.Add("shfl_result=readInvocationARB({},{});", value, src_thread_id);
+ ctx.AddU32("{}=shfl_in_bounds?shfl_result:{};", inst, value);
}
void EmitFSwizzleAdd(EmitContext& ctx, IR::Inst& inst, std::string_view op_a, std::string_view op_b,
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp
index 2868fc57d..1d77426e0 100644
--- a/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp
+++ b/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp
@@ -111,16 +111,33 @@ Id GetCbuf(EmitContext& ctx, Id result_type, Id UniformDefinitions::*member_ptr,
} else if (element_size > 1) {
const u32 log2_element_size{static_cast<u32>(std::countr_zero(element_size))};
const Id shift{ctx.Const(log2_element_size)};
- buffer_offset = ctx.OpShiftRightArithmetic(ctx.U32[1], ctx.Def(offset), shift);
+ buffer_offset = ctx.OpShiftRightLogical(ctx.U32[1], ctx.Def(offset), shift);
} else {
buffer_offset = ctx.Def(offset);
}
if (!binding.IsImmediate()) {
return ctx.OpFunctionCall(result_type, indirect_func, ctx.Def(binding), buffer_offset);
}
+
const Id cbuf{ctx.cbufs[binding.U32()].*member_ptr};
const Id access_chain{ctx.OpAccessChain(uniform_type, cbuf, ctx.u32_zero_value, buffer_offset)};
- return ctx.OpLoad(result_type, access_chain);
+ const Id val = ctx.OpLoad(result_type, access_chain);
+
+ if (offset.IsImmediate() || !ctx.profile.has_broken_robust) {
+ return val;
+ }
+
+ const auto is_float = UniformDefinitions::IsFloat(member_ptr);
+ const auto num_elements = UniformDefinitions::NumElements(member_ptr);
+ const std::array zero_vec{
+ is_float ? ctx.Const(0.0f) : ctx.Const(0u),
+ is_float ? ctx.Const(0.0f) : ctx.Const(0u),
+ is_float ? ctx.Const(0.0f) : ctx.Const(0u),
+ is_float ? ctx.Const(0.0f) : ctx.Const(0u),
+ };
+ const Id cond = ctx.OpULessThanEqual(ctx.TypeBool(), buffer_offset, ctx.Const(0xFFFFu));
+ const Id zero = ctx.OpCompositeConstruct(result_type, std::span(zero_vec.data(), num_elements));
+ return ctx.OpSelect(result_type, cond, val, zero);
}
Id GetCbufU32(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset) {
@@ -138,7 +155,7 @@ Id GetCbufElement(EmitContext& ctx, Id vector, const IR::Value& offset, u32 inde
const u32 element{(offset.U32() / 4) % 4 + index_offset};
return ctx.OpCompositeExtract(ctx.U32[1], vector, element);
}
- const Id shift{ctx.OpShiftRightArithmetic(ctx.U32[1], ctx.Def(offset), ctx.Const(2u))};
+ const Id shift{ctx.OpShiftRightLogical(ctx.U32[1], ctx.Def(offset), ctx.Const(2u))};
Id element{ctx.OpBitwiseAnd(ctx.U32[1], shift, ctx.Const(3u))};
if (index_offset > 0) {
element = ctx.OpIAdd(ctx.U32[1], element, ctx.Const(index_offset));
diff --git a/src/shader_recompiler/backend/spirv/spirv_emit_context.h b/src/shader_recompiler/backend/spirv/spirv_emit_context.h
index 7c49fd504..1aa79863d 100644
--- a/src/shader_recompiler/backend/spirv/spirv_emit_context.h
+++ b/src/shader_recompiler/backend/spirv/spirv_emit_context.h
@@ -64,6 +64,42 @@ struct UniformDefinitions {
Id F32{};
Id U32x2{};
Id U32x4{};
+
+ constexpr static size_t NumElements(Id UniformDefinitions::*member_ptr) {
+ if (member_ptr == &UniformDefinitions::U8) {
+ return 1;
+ }
+ if (member_ptr == &UniformDefinitions::S8) {
+ return 1;
+ }
+ if (member_ptr == &UniformDefinitions::U16) {
+ return 1;
+ }
+ if (member_ptr == &UniformDefinitions::S16) {
+ return 1;
+ }
+ if (member_ptr == &UniformDefinitions::U32) {
+ return 1;
+ }
+ if (member_ptr == &UniformDefinitions::F32) {
+ return 1;
+ }
+ if (member_ptr == &UniformDefinitions::U32x2) {
+ return 2;
+ }
+ if (member_ptr == &UniformDefinitions::U32x4) {
+ return 4;
+ }
+ ASSERT(false);
+ return 1;
+ }
+
+ constexpr static bool IsFloat(Id UniformDefinitions::*member_ptr) {
+ if (member_ptr == &UniformDefinitions::F32) {
+ return true;
+ }
+ return false;
+ }
};
struct StorageTypeDefinition {
diff --git a/src/shader_recompiler/profile.h b/src/shader_recompiler/profile.h
index 9ca97f6a4..38d820db2 100644
--- a/src/shader_recompiler/profile.h
+++ b/src/shader_recompiler/profile.h
@@ -9,7 +9,6 @@ namespace Shader {
struct Profile {
u32 supported_spirv{0x00010000};
-
bool unified_descriptor_binding{};
bool support_descriptor_aliasing{};
bool support_int8{};
@@ -82,6 +81,9 @@ struct Profile {
bool has_broken_spirv_subgroup_mask_vector_extract_dynamic{};
u32 gl_max_compute_smem_size{};
+
+ /// Maxwell and earlier nVidia architectures have broken robust support
+ bool has_broken_robust{};
};
} // namespace Shader
diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
index a1ec1a100..804b95989 100644
--- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
@@ -356,7 +356,11 @@ PipelineCache::PipelineCache(RasterizerVulkan& rasterizer_, const Device& device
.has_broken_fp16_float_controls = driver_id == VK_DRIVER_ID_NVIDIA_PROPRIETARY,
.ignore_nan_fp_comparisons = false,
.has_broken_spirv_subgroup_mask_vector_extract_dynamic =
- driver_id == VK_DRIVER_ID_QUALCOMM_PROPRIETARY};
+ driver_id == VK_DRIVER_ID_QUALCOMM_PROPRIETARY,
+ .has_broken_robust =
+ device.IsNvidia() && device.GetNvidiaArch() <= NvidiaArchitecture::Arch_Maxwell,
+ };
+
host_info = Shader::HostTranslateInfo{
.support_float64 = device.IsFloat64Supported(),
.support_float16 = device.IsFloat16Supported(),
diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp
index 876cec2e8..e518756d2 100644
--- a/src/video_core/vulkan_common/vulkan_device.cpp
+++ b/src/video_core/vulkan_common/vulkan_device.cpp
@@ -83,15 +83,6 @@ constexpr std::array VK_FORMAT_A4B4G4R4_UNORM_PACK16{
} // namespace Alternatives
-enum class NvidiaArchitecture {
- KeplerOrOlder,
- Maxwell,
- Pascal,
- Volta,
- Turing,
- AmpereOrNewer,
-};
-
template <typename T>
void SetNext(void**& next, T& data) {
*next = &data;
@@ -326,9 +317,9 @@ NvidiaArchitecture GetNvidiaArchitecture(vk::PhysicalDevice physical,
if (shading_rate_props.primitiveFragmentShadingRateWithMultipleViewports) {
// Only Ampere and newer support this feature
// TODO: Find a way to differentiate Ampere and Ada
- return NvidiaArchitecture::AmpereOrNewer;
+ return NvidiaArchitecture::Arch_AmpereOrNewer;
}
- return NvidiaArchitecture::Turing;
+ return NvidiaArchitecture::Arch_Turing;
}
if (exts.contains(VK_EXT_BLEND_OPERATION_ADVANCED_EXTENSION_NAME)) {
@@ -340,7 +331,7 @@ NvidiaArchitecture GetNvidiaArchitecture(vk::PhysicalDevice physical,
physical_properties.pNext = &advanced_blending_props;
physical.GetProperties2(physical_properties);
if (advanced_blending_props.advancedBlendMaxColorAttachments == 1) {
- return NvidiaArchitecture::Maxwell;
+ return NvidiaArchitecture::Arch_Maxwell;
}
if (exts.contains(VK_EXT_CONSERVATIVE_RASTERIZATION_EXTENSION_NAME)) {
@@ -350,13 +341,13 @@ NvidiaArchitecture GetNvidiaArchitecture(vk::PhysicalDevice physical,
physical_properties.pNext = &conservative_raster_props;
physical.GetProperties2(physical_properties);
if (conservative_raster_props.degenerateLinesRasterized) {
- return NvidiaArchitecture::Volta;
+ return NvidiaArchitecture::Arch_Volta;
}
- return NvidiaArchitecture::Pascal;
+ return NvidiaArchitecture::Arch_Pascal;
}
}
- return NvidiaArchitecture::KeplerOrOlder;
+ return NvidiaArchitecture::Arch_KeplerOrOlder;
}
std::vector<const char*> ExtensionListForVulkan(
@@ -436,6 +427,10 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
throw vk::Exception(VK_ERROR_INCOMPATIBLE_DRIVER);
}
+ if (is_nvidia) {
+ nvidia_arch = GetNvidiaArchitecture(physical, supported_extensions);
+ }
+
SetupFamilies(surface);
const auto queue_cis = GetDeviceQueueCreateInfos();
@@ -532,11 +527,11 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
if (is_nvidia) {
const u32 nv_major_version = (properties.properties.driverVersion >> 22) & 0x3ff;
- const auto arch = GetNvidiaArchitecture(physical, supported_extensions);
- if (arch >= NvidiaArchitecture::AmpereOrNewer) {
+ const auto arch = GetNvidiaArch();
+ if (arch >= NvidiaArchitecture::Arch_AmpereOrNewer) {
LOG_WARNING(Render_Vulkan, "Ampere and newer have broken float16 math");
features.shader_float16_int8.shaderFloat16 = false;
- } else if (arch <= NvidiaArchitecture::Volta) {
+ } else if (arch <= NvidiaArchitecture::Arch_Volta) {
if (nv_major_version < 527) {
LOG_WARNING(Render_Vulkan, "Volta and older have broken VK_KHR_push_descriptor");
RemoveExtension(extensions.push_descriptor, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME);
@@ -686,8 +681,8 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
RemoveExtension(extensions.push_descriptor, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME);
}
} else if (extensions.push_descriptor && is_nvidia) {
- const auto arch = GetNvidiaArchitecture(physical, supported_extensions);
- if (arch <= NvidiaArchitecture::Pascal) {
+ const auto arch = GetNvidiaArch();
+ if (arch <= NvidiaArchitecture::Arch_Pascal) {
LOG_WARNING(Render_Vulkan,
"Pascal and older architectures have broken VK_KHR_push_descriptor");
RemoveExtension(extensions.push_descriptor, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME);
diff --git a/src/video_core/vulkan_common/vulkan_device.h b/src/video_core/vulkan_common/vulkan_device.h
index 282a2925d..b213ed7dd 100644
--- a/src/video_core/vulkan_common/vulkan_device.h
+++ b/src/video_core/vulkan_common/vulkan_device.h
@@ -177,6 +177,15 @@ enum class FormatType { Linear, Optimal, Buffer };
/// Subgroup size of the guest emulated hardware (Nvidia has 32 threads per subgroup).
const u32 GuestWarpSize = 32;
+enum class NvidiaArchitecture {
+ Arch_KeplerOrOlder,
+ Arch_Maxwell,
+ Arch_Pascal,
+ Arch_Volta,
+ Arch_Turing,
+ Arch_AmpereOrNewer,
+};
+
/// Handles data specific to a physical device.
class Device {
public:
@@ -670,6 +679,14 @@ public:
return false;
}
+ bool IsNvidia() const noexcept {
+ return properties.driver.driverID == VK_DRIVER_ID_NVIDIA_PROPRIETARY;
+ }
+
+ NvidiaArchitecture GetNvidiaArch() const noexcept {
+ return nvidia_arch;
+ }
+
private:
/// Checks if the physical device is suitable and configures the object state
/// with all necessary info about its properties.
@@ -788,6 +805,7 @@ private:
bool supports_conditional_barriers{}; ///< Allows barriers in conditional control flow.
u64 device_access_memory{}; ///< Total size of device local memory in bytes.
u32 sets_per_pool{}; ///< Sets per Description Pool
+ NvidiaArchitecture nvidia_arch{NvidiaArchitecture::Arch_AmpereOrNewer};
// Telemetry parameters
std::set<std::string, std::less<>> supported_extensions; ///< Reported Vulkan extensions.
diff --git a/src/yuzu/configuration/configure_vibration.cpp b/src/yuzu/configuration/configure_vibration.cpp
index d765e808a..68c28b320 100644
--- a/src/yuzu/configuration/configure_vibration.cpp
+++ b/src/yuzu/configuration/configure_vibration.cpp
@@ -89,7 +89,7 @@ void ConfigureVibration::VibrateController(Core::HID::ControllerTriggerType type
auto& player = Settings::values.players.GetValue()[player_index];
auto controller = hid_core.GetEmulatedControllerByIndex(player_index);
- const int vibration_strenght = vibration_spinboxes[player_index]->value();
+ const int vibration_strength = vibration_spinboxes[player_index]->value();
const auto& buttons = controller->GetButtonsValues();
bool button_is_pressed = false;
@@ -105,10 +105,10 @@ void ConfigureVibration::VibrateController(Core::HID::ControllerTriggerType type
return;
}
- const int old_vibration_enabled = player.vibration_enabled;
- const bool old_vibration_strenght = player.vibration_strength;
+ const bool old_vibration_enabled = player.vibration_enabled;
+ const int old_vibration_strength = player.vibration_strength;
player.vibration_enabled = true;
- player.vibration_strength = vibration_strenght;
+ player.vibration_strength = vibration_strength;
const Core::HID::VibrationValue vibration{
.low_amplitude = 1.0f,
@@ -121,7 +121,7 @@ void ConfigureVibration::VibrateController(Core::HID::ControllerTriggerType type
// Restore previous values
player.vibration_enabled = old_vibration_enabled;
- player.vibration_strength = old_vibration_strenght;
+ player.vibration_strength = old_vibration_strength;
}
void ConfigureVibration::StopVibrations() {